knitr::opts_chunk$set(
    message = FALSE,
    warning = FALSE,
    comment = NA,
    include = FALSE,
    tidy = TRUE
)

1 R nerede kullanılır

  • Veri düzenleme
  • İstatistik analiz
  • Web sayfası hazırlama (Statik/Dinamik)
  • Sunum hazırlama
  • Programlama
  • Otomatik, periodik ve tekrarlanabilir rapor hazırlama
  • pdf, html, ppt oluşturma
  • tez yazma
  • kitap yazma
  • CV oluşturma
  • poster hazırlama
  • rapor şablonu oluşturma

2 R generation

R yıllar içinde çok fazla değişim gösterdi

https://rss.onlinelibrary.wiley.com/doi/10.1111/j.1740-9713.2018.01169.x

:scale 30%


3 R yükleme

http://www.youtube.com/watch?v=XcBLEVknqvY

3.1 What is R?

3.3 RStudio


3.4 RStudio

https://www.rstudio.com/

https://www.rstudio.com/products/rstudio/download/

https://moderndive.com/2-getting-started.html



3.4.1 RStudio eklentileri

  • Discover and install useful RStudio addins

https://cran.r-project.org/web/packages/addinslist/README.html

https://rstudio.github.io/rstudioaddins/

devtools::install_github("rstudio/addinexamples", type = "source")

5 R zor şeyler için kolay, kolay şeyler için zor

R Syntax Comparison::CHEAT SHEET

https://www.amelia.mn/Syntax-cheatsheet.pdf



6 R paketleri

6.1 Neden paketler var




6.3 Kendi paket evrenini oluştur


6.4 R paket yükleme

install.packages("tidyverse", dependencies = TRUE)
install.packages("jmv", dependencies = TRUE)
install.packages("questionr", dependencies = TRUE)
install.packages("Rcmdr", dependencies = TRUE)
install.packages("summarytools")
# install.packages("tidyverse", dependencies = TRUE)
# install.packages("jmv", dependencies = TRUE)
# install.packages("questionr", dependencies = TRUE)
# install.packages("Rcmdr", dependencies = TRUE)
# install.packages("summarytools")

6.5 Paket çağırma

# require(tidyverse)
# require(jmv)
# require(questionr)
# library(summarytools)
# library(gganimate)

7 R için yardım bulma

# ?mean
# ??efetch
# help(merge)
# example(merge)

  • Vignette

:scale 80%


https://stackoverflow.com/

  • Google uygun anahtar kelime



  • Google’da ararken [R] yazmak da işe yarayabiliyor.

  • searcher package 📦


http://cran.r-project.org/doc/contrib/Baggott-refcard-v2.pdf

https://www.rstudio.com/resources/cheatsheets/

  • Awesome R

https://github.com/qinwf/awesome-R#readme

https://awesome-r.com/

  • Twitter

https://twitter.com/hashtag/rstats?src=hash


  • Use Reproducible Examples When Asking

9 RStudio ile veri yükleme

https://support.rstudio.com/hc/en-us/articles/218611977-Importing-Data-with-RStudio


9.1 Excel

9.2 SPSS

9.3 CSV


10 Veriyi görüntüleme


11 Veriyi görüntüleme

# library(nycflights13)
# summary(flights)
View(data)
data
head
tail
glimpse
str
skimr::skim()

12 Veriyi değiştirme

12.1 Veriyi kod ile değiştirelim

12.2 Veriyi eklentilerle değiştirme

:scale 50%


12.3 RStudio aracılığıyla recode

questionr paketi kullanılacak

:scale 50%


https://juba.github.io/questionr/articles/recoding_addins.html




13 Basit tanımlayıcı istatistikler

summary()
mean
median
min
max
sd
table()

library(readr)
irisdata <- read_csv("data/iris.csv")
Parsed with column specification:
cols(
  Sepal.Length = col_double(),
  Sepal.Width = col_double(),
  Petal.Length = col_double(),
  Petal.Width = col_double(),
  Species = col_character()
)
jmv::descriptives(
    data = irisdata,
    vars = "Sepal.Length",
    splitBy = "Species",
    freq = TRUE,
    hist = TRUE,
    dens = TRUE,
    bar = TRUE,
    box = TRUE,
    violin = TRUE,
    dot = TRUE,
    mode = TRUE,
    sum = TRUE,
    sd = TRUE,
    variance = TRUE,
    range = TRUE,
    se = TRUE,
    skew = TRUE,
    kurt = TRUE,
    quart = TRUE,
    pcEqGr = TRUE)

 DESCRIPTIVES

 Descriptives                                          
 ───────────────────────────────────────────────────── 
                          Species       Sepal.Length   
 ───────────────────────────────────────────────────── 
   N                      setosa                  50   
                          versicolor              50   
                          virginica               50   
   Missing                setosa                   0   
                          versicolor               0   
                          virginica                0   
   Mean                   setosa                5.01   
                          versicolor            5.94   
                          virginica             6.59   
   Std. error mean        setosa              0.0498   
                          versicolor          0.0730   
                          virginica           0.0899   
   Median                 setosa                5.00   
                          versicolor            5.90   
                          virginica             6.50   
   Mode                   setosa                5.00   
                          versicolor            5.50   
                          virginica             6.30   
   Sum                    setosa                 250   
                          versicolor             297   
                          virginica              329   
   Standard deviation     setosa               0.352   
                          versicolor           0.516   
                          virginica            0.636   
   Variance               setosa               0.124   
                          versicolor           0.266   
                          virginica            0.404   
   Range                  setosa                1.50   
                          versicolor            2.10   
                          virginica             3.00   
   Minimum                setosa                4.30   
                          versicolor            4.90   
                          virginica             4.90   
   Maximum                setosa                5.80   
                          versicolor            7.00   
                          virginica             7.90   
   Skewness               setosa               0.120   
                          versicolor           0.105   
                          virginica            0.118   
   Std. error skewness    setosa               0.337   
                          versicolor           0.337   
                          virginica            0.337   
   Kurtosis               setosa              -0.253   
                          versicolor          -0.533   
                          virginica           0.0329   
   Std. error kurtosis    setosa               0.662   
                          versicolor           0.662   
                          virginica            0.662   
   25th percentile        setosa                4.80   
                          versicolor            5.60   
                          virginica             6.23   
   50th percentile        setosa                5.00   
                          versicolor            5.90   
                          virginica             6.50   
   75th percentile        setosa                5.20   
                          versicolor            6.30   
                          virginica             6.90   
 ───────────────────────────────────────────────────── 


# install.packages("scatr")

scatr::scat(
    data = irisdata,
    x = "Sepal.Length",
    y = "Sepal.Width",
    group = "Species",
    marg = "dens",
    line = "linear",
    se = TRUE)

13.1 summarytools

https://cran.r-project.org/web/packages/summarytools/vignettes/Introduction.html

library(summarytools)
summarytools::freq(iris$Species, style = "rmarkdown")

13.1.1 Frequencies

13.1.1.1 iris$Species

Type: Factor

  Freq % Valid % Valid Cum. % Total % Total Cum.
setosa 50 33.33 33.33 33.33 33.33
versicolor 50 33.33 66.67 33.33 66.67
virginica 50 33.33 100.00 33.33 100.00
<NA> 0 0.00 100.00
Total 150 100.00 100.00 100.00 100.00

summarytools::freq(iris$Species, report.nas = FALSE, style = "rmarkdown", headings = FALSE)
with(tobacco, print(ctable(smoker, diseased), method = 'render'))
with(tobacco,
     print(ctable(smoker, diseased, prop = 'n', totals = FALSE),
           omit.headings = TRUE, method = "render"))

summarytools::descr(iris, style = "rmarkdown")

descr(iris,
      stats = c("mean", "sd", "min", "med", "max"),
      transpose = TRUE,
      headings = FALSE,
      style = "rmarkdown")

# view(dfSummary(iris))


dfSummary(tobacco,
          plain.ascii = FALSE,
          style = "grid")


# First save the results

iris_stats_by_species <- by(data = iris,
                            INDICES = iris$Species,
                            FUN = descr, stats = c("mean", "sd", "min", "med", "max"),
                            transpose = TRUE)

# Then use view(), like so:

view(iris_stats_by_species, method = "pander", style = "rmarkdown")

# view(iris_stats_by_species)


data(tobacco) # tobacco is an example dataframe included in the package
BMI_by_age <- with(tobacco,
                   by(BMI, age.gr, descr,
                      stats = c("mean", "sd", "min", "med", "max")))
view(BMI_by_age, "pander", style = "rmarkdown")

BMI_by_age <- with(tobacco,
                   by(BMI, age.gr, descr,  transpose = TRUE,
                      stats = c("mean", "sd", "min", "med", "max")))

view(BMI_by_age, "pander", style = "rmarkdown", omit.headings = TRUE)

tobacco_subset <- tobacco[ ,c("gender", "age.gr", "smoker")]
freq_tables <- lapply(tobacco_subset, freq)

# view(freq_tables, footnote = NA, file = 'freq-tables.html')

what.is(iris)

freq(tobacco$gender, style = 'rmarkdown')

print(freq(tobacco$gender), method = 'render')

13.2 skimr

library(skimr)
skim(df)

13.3 DataExplorer

library(DataExplorer)
DataExplorer::create_report(df)


13.5 Grafikler

# library(ggplot2)
# library(mosaic)
# mPlot(irisdata)

ctable(tobacco$gender, tobacco$smoker, style = 'rmarkdown')

print(ctable(tobacco$gender, tobacco$smoker), method = 'render')

descr(tobacco, style = 'rmarkdown')

print(descr(tobacco), method = 'render', table.classes = 'st-small')

dfSummary(tobacco, style = 'grid', plain.ascii = FALSE)

print(dfSummary(tobacco, graph.magnif = 0.75), method = 'render')



14 Bazı arayüzler

14.1 Rcmdr

library(Rcmdr)

Rcmdr::Commander()
  • A Comparative Review of the R Commander GUI for R

http://r4stats.com/articles/software-reviews/r-commander/


16 Sonraki Konular

  • RStudio ile GitHub kullanımı
  • R Markdown ve R Notebook ile tekrarlanabilir rapor
  • Hipotez testleri

17 Geri Bildirim



# Save Final Data

saved data after analysis to `Data-After-Analysis.xlsx`.

saveRDS(mydata, "Data-After-Analysis.rds")

writexl::write_xlsx(mydata, "Data-After-Analysis.xlsx")

file.info("Data-After-Analysis.xlsx")$ctime

18 Libraries Used

citation()
citation("tidyverse")
citation("foreign")
citation("tidylog")
citation("janitor")
citation("jmv")
citation("tangram")
citation("finalfit")
citation("summarytools")
citation("ggstatplot")
citation("readxl")

report::cite_packages(session = sessionInfo())

sessionInfo()

19 Notes

Completed on 2019-09-24 19:34:23.

Serdar Balci, MD, Pathologist

https://rpubs.com/sbalci/CV
https://sbalci.github.io/
https://github.com/sbalci


CommitMessage <- paste("updated on ", Sys.time(), sep = "")

wd <- getwd()

gitCommand <- paste("cd ", wd, " \n git add . \n git commit --message '", CommitMessage, "' \n git push origin master \n", sep = "")

system(command = gitCommand, intern = TRUE
)

  1. Bu bir derlemedir, mümkün mertebe alıntılara referans vermeye çalıştım.↩︎

LS0tCnRpdGxlOiBSIGlsZSBhbmFsaXplIGJhxZ9sYXJrZW5eW0J1IGJpciBkZXJsZW1lZGlyLCBtw7xta8O8biBtZXJ0ZWJlIGFsxLFudMSxbGFyYSByZWZlcmFucwogIHZlcm1leWUgw6dhbMSxxZ90xLFtLl0KYXV0aG9yOiAiRGVybGV5ZW4gW1NlcmRhciBCYWxjxLEsIE1ELCBQYXRob2xvZ2lzdF0oaHR0cHM6Ly9zYmFsY2kuZ2l0aHViLmlvLykiCmluc3RpdHV0ZTogIltzZXJkYXJiYWxjaS5jb21dKGh0dHBzOi8vd3d3LnNlcmRhcmJhbGNpLmNvbSkiCmRhdGU6ICJgciBmb3JtYXQoU3lzLkRhdGUoKSlgIgpvdXRwdXQ6CiAgcmV2ZWFsanM6OnJldmVhbGpzX3ByZXNlbnRhdGlvbjoKICB4YXJpbmdhbjo6bW9vbl9yZWFkZXI6CiAgICBsaWJfZGlyOiBsaWJzCiAgICBuYXR1cmU6CiAgICAgIGJlZm9yZUluaXQ6IFsibWFjcm9zLmpzIiwgImh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyJdCiAgICAgIGhpZ2hsaWdodFN0eWxlOiBnaXRodWIKICAgICAgaGlnaGxpZ2h0TGluZXM6IHRydWUKICAgICAgY291bnRJbmNyZW1lbnRhbFNsaWRlczogZmFsc2UKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgaHRtbF9ub3RlYm9vazoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGhpZ2hsaWdodDoga2F0ZQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRoZW1lOiBmbGF0bHkKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogeWVzCiAgcGRmX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogJzUnCiAgaHRtbF9kb2N1bWVudDoKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGtlZXBfbWQ6IHllcwogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNQogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCgo8IS0tIE9wZW4gYWxsIGxpbmtzIGluIG5ldyB0YWItLT4gIAo8YmFzZSB0YXJnZXQ9Il9ibGFuayIvPiAgIAoKPCEtLSBHbyB0byB3d3cuYWRkdGhpcy5jb20vZGFzaGJvYXJkIHRvIGN1c3RvbWl6ZSB5b3VyIHRvb2xzIC0tPiA8c2NyaXB0IHR5cGU9InRleHQvamF2YXNjcmlwdCIgc3JjPSIvL3M3LmFkZHRoaXMuY29tL2pzLzMwMC9hZGR0aGlzX3dpZGdldC5qcyNwdWJpZD1yYS01YmMzNjkwMGE0MDUwOTBiIj4gIAo8L3NjcmlwdD4KCjwhLS0gWyFbXShodHRwOi8vcmVzLmNsb3VkaW5hcnkuY29tL2R5ZDkxMWttaC9pbWFnZS91cGxvYWQvZl9hdXRvLHFfYXV0bzpiZXN0L3YxNTMwMTEzMDc3L0ltYWdlXzJfdmZ5NDhiLnBuZyldKGh0dHBzOi8vd3d3LmRhdGFjYW1wLmNvbS9jb21tdW5pdHkvdHV0b3JpYWxzL2RhdGEtc2NpZW5jZS1waXRmYWxscykgLS0+CgoKYGBge3Igc2V0dXAgZ2xvYmFsIGNodW5rIHNldHRpbmdzfQprbml0cjo6b3B0c19jaHVuayRzZXQoCgltZXNzYWdlID0gRkFMU0UsCgl3YXJuaW5nID0gRkFMU0UsCgljb21tZW50ID0gTkEsCglpbmNsdWRlID0gRkFMU0UsCgl0aWR5ID0gVFJVRQopCmBgYAoKCiMgUiBuZXJlZGUga3VsbGFuxLFsxLFyCgotIFZlcmkgZMO8emVubGVtZQotIMSwc3RhdGlzdGlrIGFuYWxpegotIFdlYiBzYXlmYXPEsSBoYXrEsXJsYW1hIChTdGF0aWsvRGluYW1paykKLSBTdW51bSBoYXrEsXJsYW1hCi0gUHJvZ3JhbWxhbWEKLSBPdG9tYXRpaywgcGVyaW9kaWsgdmUgdGVrcmFybGFuYWJpbGlyIHJhcG9yIGhhesSxcmxhbWEKLSBwZGYsIGh0bWwsIHBwdCBvbHXFn3R1cm1hCi0gdGV6IHlhem1hCi0ga2l0YXAgeWF6bWEKLSBDViBvbHXFn3R1cm1hCi0gcG9zdGVyIGhhesSxcmxhbWEKLSByYXBvciDFn2FibG9udSBvbHXFn3R1cm1hCi0gLi4uCgotLS0KCiMgUiBnZW5lcmF0aW9uCgpSIHnEsWxsYXIgacOnaW5kZSDDp29rIGZhemxhIGRlxJ9pxZ9pbSBnw7ZzdGVyZGkKCmh0dHBzOi8vcnNzLm9ubGluZWxpYnJhcnkud2lsZXkuY29tL2RvaS8xMC4xMTExL2ouMTc0MC05NzEzLjIwMTguMDExNjkueAoKIVtdKGh0dHBzOi8vd29sLXByb2QtY2RuLmxpdGVyYXR1bW9ubGluZS5jb20vcGItYXNzZXRzL2pvdXJuYWwtYmFubmVycy8xNzQwOTcxMy0xNTAxMzg0NzU2MDM3LmpwZykKCiFbOnNjYWxlIDMwJV0oaHR0cHM6Ly93b2wtcHJvZC1jZG4ubGl0ZXJhdHVtb25saW5lLmNvbS9jbXMvYXR0YWNobWVudC8xYTQ5YzA3Yi1iNTZmLTQzMjctOGU5Mi03ODI3ZWY1MWE3YmIvc2lnbjExNjktZ3JhLTAwMDItbS5qcGcpCgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MocGF0aCA9ICJodHRwczovL3dvbC1wcm9kLWNkbi5saXRlcmF0dW1vbmxpbmUuY29tL2Ntcy9hdHRhY2htZW50LzFhNDljMDdiLWI1NmYtNDMyNy04ZTkyLTc4MjdlZjUxYTdiYi9zaWduMTE2OS1ncmEtMDAwMi1tLmpwZyIpCmBgYAoKCi0tLQoKIyBSIHnDvGtsZW1lCgpodHRwOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9WGNCTEVWa25xdlkKCiFbV2hhdCBpcyBSP10oaHR0cDovL2ltZy55b3V0dWJlLmNvbS92aS9YY0JMRVZrbnF2WS8wLmpwZykKLS0tCgojIyBSLXByb2plY3QKCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnLwoKLS0tCgojIyBSU3R1ZGlvCgoKIVtdKGh0dHBzOi8vaXNtYXljLmdpdGh1Yi5pby90YWxrcy9uZXNzLWluZmVyL2ltZy9lbmdpbmUucG5nKQoKLS0tCgojIyBSU3R1ZGlvCgpbaHR0cHM6Ly93d3cucnN0dWRpby5jb20vXShodHRwczovL3d3dy5yc3R1ZGlvLmNvbS8pCgpbaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC9dKGh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQvKQoKW2h0dHBzOi8vbW9kZXJuZGl2ZS5jb20vMi1nZXR0aW5nLXN0YXJ0ZWQuaHRtbF0oaHR0cHM6Ly9tb2Rlcm5kaXZlLmNvbS8yLWdldHRpbmctc3RhcnRlZC5odG1sKQoKLS0tCgpbIVtdKGh0dHA6Ly93d3ctdXNlcnMueW9yay5hYy51ay9+ZXIxMy9SU3R1ZGlvJTIwQW5hdG9teS5zdmcpXShodHRwczovL2J1enpyYmVlbGluZS5ibG9nLzIwMTgvMDcvMDQvcnN0dWRpby1hbmF0b215LykKCgoKLS0tCgojIyMgUlN0dWRpbyBla2xlbnRpbGVyaQoKLSBEaXNjb3ZlciBhbmQgaW5zdGFsbCB1c2VmdWwgUlN0dWRpbyBhZGRpbnMKCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9hZGRpbnNsaXN0L1JFQURNRS5odG1sCgpodHRwczovL3JzdHVkaW8uZ2l0aHViLmlvL3JzdHVkaW9hZGRpbnMvCgoKYGBgCmRldnRvb2xzOjppbnN0YWxsX2dpdGh1YigicnN0dWRpby9hZGRpbmV4YW1wbGVzIiwgdHlwZSA9ICJzb3VyY2UiKQpgYGAKCgotLS0KCiMgTWFjT1MgacOnaW4KCiMjIFgxMQoKaHR0cHM6Ly93d3cueHF1YXJ0ei5vcmcvCgojIyBKYXZhIE9TCgpodHRwczovL3N1cHBvcnQuYXBwbGUuY29tL2tiL2RsMTU3MgoKLS0tCgoKIyBSIHpvciDFn2V5bGVyIGnDp2luIGtvbGF5LCBrb2xheSDFn2V5bGVyIGnDp2luIHpvcgoKCi0gW1IgbWFrZXMgZWFzeSB0aGluZ3MgaGFyZCwgYW5kIGhhcmQgdGhpbmdzIGVhc3ldKGh0dHA6Ly9yNHN0YXRzLmNvbS9hcnRpY2xlcy93aHktci1pcy1oYXJkLXRvLWxlYXJuLykKCgotIEF5bsSxIMWfZXlpIMOnb2sgZmF6bGEgxZ9la2lsZGUgeWFwbWFrIG3DvG1rw7xuCgpSIFN5bnRheCBDb21wYXJpc29uOjpDSEVBVCBTSEVFVAoKaHR0cHM6Ly93d3cuYW1lbGlhLm1uL1N5bnRheC1jaGVhdHNoZWV0LnBkZgoKCi0tLQoKCjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPjxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9SU3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNSU3RhdHM8L2E+IOKAlCBUaGVyZSBhcmUgYWx3YXlzIHNldmVyYWwgd2F5cyB0byBkbyB0aGUgc2FtZSB0aGluZy4uLiBuaWNlIGV4YW1wbGUgb24gd2l0aCB0aGUgaWRlbnRpdHkgbWF0cml4IGJ5IDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vVGVhU3RhdHM/cmVmX3NyYz10d3NyYyU1RXRmdyI+QFRlYVN0YXRzPC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vTzNHWGRQaU0zMiI+aHR0cHM6Ly90LmNvL08zR1hkUGlNMzI8L2E+PC9wPiZtZGFzaDsgQ29saW4gRmF5IPCfpJggKEBfQ29saW5GYXkpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vX0NvbGluRmF5L3N0YXR1cy8xMTEyNzQ2NjMzNDY3NTE4OTc3P3JlZl9zcmM9dHdzcmMlNUV0ZnciPkFwcmlsIDEsIDIwMTk8L2E+PC9ibG9ja3F1b3RlPgo8c2NyaXB0IGFzeW5jIHNyYz0iaHR0cHM6Ly9wbGF0Zm9ybS50d2l0dGVyLmNvbS93aWRnZXRzLmpzIiBjaGFyc2V0PSJ1dGYtOCI+PC9zY3JpcHQ+CgotLS0KCgojIFIgcGFrZXRsZXJpCgoKIyMgTmVkZW4gcGFrZXRsZXIgdmFyCgpbIVtdKGh0dHBzOi8vaXNtYXljLmdpdGh1Yi5pby90YWxrcy9uZXNzLWluZmVyL2ltZy9hcHBzdG9yZS5wbmcpXShodHRwczovL2lzbWF5Yy5naXRodWIuaW8vdGFsa3MvbmVzcy1pbmZlci9zbGlkZV9kZWNrLmh0bWwjNykKCi0tLQoKPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPkkgbG92ZSB0aGUgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4gY29tbXVuaXR5Ljxicj5Tb21lb25lIGlzIGxpa2UsICZxdW90O29oIGhleSBwZWVwcywgSSBzYXcgYSBiaWcgbmVlZCBmb3IgdGhpcyBtdW5kYW5lIGJ1dCBkaWZmaWN1bHQgdGFzayB0aGF0IEkgaW5mcmVxdWVudGx5IGRvLCBzbyBJIGNyZWF0ZWQgYSBwYWNrYWdlIHRoYXQgd2lsbCBsaXRlcmFsbHkgc2NyYXBlIHRoZSBsYXN0IGJpdHMgb2YgcGVhbnV0IGJ1dHRlciBvdXQgb2YgdGhlIGphciBmb3IgeW91LiBJdCYjMzk7cyBjYWxsZWQgcGJwbHlyLiZxdW90Ozxicj5XaGF0IGEgdHJpYmUuPC9wPiZtZGFzaDsgRnJhbmsgRWxhdnNreSDhtLDhtYPhtZfhtYMg4bWC4bam4ba74bWDyrPhtYggKEBGcmFua2x5X0RhdGEpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vRnJhbmtseV9EYXRhL3N0YXR1cy8xMDE0MTg5MDk1Mjk0MjkxOTY4P3JlZl9zcmM9dHdzcmMlNUV0ZnciPkp1bHkgMywgMjAxODwvYT48L2Jsb2NrcXVvdGU+Cgo8IS0tIC0tLSAtLT4KCjwhLS0gaHR0cHM6Ly9ibG9nLm1pdGNoZWxsb2hhcmF3aWxkLmNvbS9ibG9nL3VzZXItMjAxOC1mZWF0dXJlLXdhbGwvIC0tPgoKLS0tCgohW10oaHR0cHM6Ly9ibG9nLm1pdGNoZWxsb2hhcmF3aWxkLmNvbS9ibG9nLzIwMTgtMDctMTEtdXNlci0yMDE4LWZlYXR1cmUtd2FsbF9maWxlcy9maW5hbC5qcGcpCgotLS0KCiMjIFBha2V0bGVyaSBuZXJlZGVuIGJ1bGFiaWxpcml6CgotIEF2YWlsYWJsZSBDUkFOIFBhY2thZ2VzIEJ5IE5hbWUgIApodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvYXZhaWxhYmxlX3BhY2thZ2VzX2J5X25hbWUuaHRtbAoKLSBDUkFOIFRhc2sgVmlld3MgIApodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvdmlld3MvCgotIEJpb2NvbmR1Y3RvciAgCmh0dHBzOi8vd3d3LmJpb2NvbmR1Y3Rvci5vcmcKCi0gUmVjb21tZW5kUiAgCmh0dHA6Ly9yZWNvbW1lbmRyLmluZm8vCgotIHBrZ3NlYXJjaCAgCkNSQU4gcGFja2FnZSBzZWFyY2ggIApodHRwczovL2dpdGh1Yi5jb20vbWV0YWNyYW4vcGtnc2VhcmNoCgotIENSQU5zZWFyY2hlciAgCmh0dHBzOi8vZ2l0aHViLmNvbS9SaG9JbmMvQ1JBTnNlYXJjaGVyICAKCi0gQXdlc29tZSBSICAKaHR0cHM6Ly9hd2Vzb21lLXIuY29tLyAgCgotLS0KCiMjIEtlbmRpIHBha2V0IGV2cmVuaW5pIG9sdcWfdHVyCgotIHBrZ3ZlcnNlOiBCdWlsZCBhIE1ldGEtUGFja2FnZSBVbml2ZXJzZSAgCmh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9wa2d2ZXJzZS9pbmRleC5odG1sCgoKLS0tCgojIyBSIHBha2V0IHnDvGtsZW1lCgpgYGAKaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKaW5zdGFsbC5wYWNrYWdlcygiam12IiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKaW5zdGFsbC5wYWNrYWdlcygicXVlc3Rpb25yIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKaW5zdGFsbC5wYWNrYWdlcygiUmNtZHIiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQppbnN0YWxsLnBhY2thZ2VzKCJzdW1tYXJ5dG9vbHMiKQpgYGAKCmBgYHtyIHBha2V0IHnDvGtsZW1lfQojIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIsIGRlcGVuZGVuY2llcyA9IFRSVUUpCiMgaW5zdGFsbC5wYWNrYWdlcygiam12IiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKIyBpbnN0YWxsLnBhY2thZ2VzKCJxdWVzdGlvbnIiLCBkZXBlbmRlbmNpZXMgPSBUUlVFKQojIGluc3RhbGwucGFja2FnZXMoIlJjbWRyIiwgZGVwZW5kZW5jaWVzID0gVFJVRSkKIyBpbnN0YWxsLnBhY2thZ2VzKCJzdW1tYXJ5dG9vbHMiKQpgYGAKCi0tLQoKIyMgUGFrZXQgw6dhxJ/EsXJtYQoKYGBge3IgcGFrZXQgY2FnaXJtYSwgZXJyb3I9RkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgd2FybmluZyA9IEZBTFNFLCBldmFsID0gVFJVRSwgaW5jbHVkZSA9IFRSVUV9CiMgcmVxdWlyZSh0aWR5dmVyc2UpCiMgcmVxdWlyZShqbXYpCiMgcmVxdWlyZShxdWVzdGlvbnIpCiMgbGlicmFyeShzdW1tYXJ5dG9vbHMpCiMgbGlicmFyeShnZ2FuaW1hdGUpCmBgYAoKCgotLS0KCiMgUiBpw6dpbiB5YXJkxLFtIGJ1bG1hCgoKYGBge3IgeWFyZMSxbX0KIyA/bWVhbgojID8/ZWZldGNoCiMgaGVscChtZXJnZSkKIyBleGFtcGxlKG1lcmdlKQpgYGAKCi0tLQoKLSBWaWduZXR0ZQoKIVs6c2NhbGUgODAlXShmaWd1cmVzL3ZpZ25ldHRlLnBuZykKCi0tLQoKLSBSRG9jdW1lbnRhdGlvbgpodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcKCi0gUiBQYWNrYWdlIERvY3VtZW50YXRpb24KaHR0cHM6Ly9yZHJyLmlvLwoKLSBHaXRIdWIKCi0gU3RhY2tvdmVyZmxvdwoKaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS8KCi0gR29vZ2xlIHV5Z3VuIGFuYWh0YXIga2VsaW1lCgotLS0KCjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD48YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5Ib3cgSSB1c2UgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4gPGJyPmgvdCA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL1RoZVByYWN0aWNhbERldj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AVGhlUHJhY3RpY2FsRGV2PC9hPiA8YSBocmVmPSJodHRwczovL3QuY28vZXJSblRHMFVqciI+cGljLnR3aXR0ZXIuY29tL2VyUm5URzBVanI8L2E+PC9wPiZtZGFzaDsgRW1pbHkgQm92ZWUgKEBlYm92ZWUwOSkgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9lYm92ZWUwOS9zdGF0dXMvMTAyODAzNzU5NDk0NzQ4NTY5Nj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5BdWd1c3QgMTAsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgoKCi0tLQoKCiFbXShmaWd1cmVzL0dvb2dsZS1wYWNrYWdlLW5hbWUucG5nKQoKLS0tCgoKCiFbXShmaWd1cmVzL0dvb2dsZS1zdGFydC13aXRoLVIucG5nKQoKCi0gR29vZ2xlJ2RhIGFyYXJrZW4gYFtSXWAgeWF6bWFrIGRhIGnFn2UgeWFyYXlhYmlsaXlvci4KCgotLS0KCi0gc2VhcmNoZXIgcGFja2FnZSDwn5OmCgoKWyFbXShodHRwczovL2NhbW8uZ2l0aHVidXNlcmNvbnRlbnQuY29tLzEyZjBlMmQxODA0N2YxYjVmMzZmYmViMDlhMWQwZTU0ODIzNjg4M2YvNjg3NDc0NzA3MzNhMmYyZjY5MmU2OTZkNjc3NTcyMmU2MzZmNmQyZjVhNzEzMjcyNjczNjQ3MmU2NzY5NjYpXShodHRwczovL2dpdGh1Yi5jb20vY29hdGxlc3Mvc2VhcmNoZXIpCgoKCi0tLQoKLSBBd2Vzb21lIENoZWF0c2hlZXQKaHR0cHM6Ly9naXRodWIuY29tL2RldGFpbHlhbmcvYXdlc29tZS1jaGVhdHNoZWV0CgpodHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnL2RvYy9jb250cmliL0JhZ2dvdHQtcmVmY2FyZC12Mi5wZGYKCmh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Jlc291cmNlcy9jaGVhdHNoZWV0cy8KCgotIEF3ZXNvbWUgUgoKaHR0cHM6Ly9naXRodWIuY29tL3FpbndmL2F3ZXNvbWUtUiNyZWFkbWUKCmh0dHBzOi8vYXdlc29tZS1yLmNvbS8KCgotIFR3aXR0ZXIKCmh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gKCi0tLQoKCi0gVXNlIFJlcHJvZHVjaWJsZSBFeGFtcGxlcyBXaGVuIEFza2luZyAgCgo8YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5Hb3QgYSBxdWVzdGlvbiB0byBhc2sgb24gPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9TbGFja0hRP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkBTbGFja0hRPC9hPiBvciBwb3N0IG9uIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vZ2l0aHViP3JlZl9zcmM9dHdzcmMlNUV0ZnciPkBnaXRodWI8L2E+PyBObyB0aW1lIHRvIHJlYWQgdGhlIGxvbmcgcG9zdCBvbiBob3cgdG8gdXNlIHJlcHJleD8gSGVyZSBpcyBhIDIwLXNlY29uZCBnaWYgZm9yIHlvdSB0byBmb3JtYXQgeW91ciBSIGNvZGVzIG5pY2VseSBhbmQgZm9yIG90aGVycyB0byByZXByb2R1Y2UgeW91ciBwcm9ibGVtLiAoQW4gZXhhbXBsZSBmcm9tIGEgdGFsayBnaXZlbiBieSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL0plbm55QnJ5YW4/cmVmX3NyYz10d3NyYyU1RXRmdyI+QEplbm55QnJ5YW48L2E+KSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXQ/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdDwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL2dwdUdYcEZJc1giPnBpYy50d2l0dGVyLmNvbS9ncHVHWHBGSXNYPC9hPjwvcD4mbWRhc2g7IFpoaVlhbmcgKEB6aGlpaXlhbmcpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vemhpaWl5YW5nL3N0YXR1cy8xMDUzMDA2MDAzNzExNTY5OTIwP3JlZl9zcmM9dHdzcmMlNUV0ZnciPk9jdG9iZXIgMTgsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD4KCgotIEtlZXBpbmcgdXAgdG8gZGF0ZSB3aXRoIFIgbmV3cyAgCmh0dHBzOi8vbWFzYWxtb24uZXUvMjAxOS8wMS8yNS91cHRvZGF0ZS8gIAoKLS0tCgojIFIgc3R1ZGlvIGlsZSBwcm9qZSBvbHXFn3R1cm1hCgpodHRwczovL3N1cHBvcnQucnN0dWRpby5jb20vaGMvZW4tdXMvYXJ0aWNsZXMvMjAwNTI2MjA3LVVzaW5nLVByb2plY3RzCgohW10oaHR0cDovL3d3dy5yc3R1ZGlvLmNvbS9pbWFnZXMvZG9jcy9wcm9qZWN0c19uZXcucG5nKQoKLS0tCgojIFJTdHVkaW8gaWxlIHZlcmkgecO8a2xlbWUKCmh0dHBzOi8vc3VwcG9ydC5yc3R1ZGlvLmNvbS9oYy9lbi11cy9hcnRpY2xlcy8yMTg2MTE5NzctSW1wb3J0aW5nLURhdGEtd2l0aC1SU3R1ZGlvCgohW10oaHR0cHM6Ly9zdXBwb3J0LnJzdHVkaW8uY29tL2hjL2VuLXVzL2FydGljbGVfYXR0YWNobWVudHMvMjA2Mjc3NjE4L2RhdGEtaW1wb3J0LW92ZXJ2aWV3LmdpZikKCi0tLQoKIyMgRXhjZWwKCiMjIFNQU1MKCiMjIENTVgoKCi0tLQoKIyBWZXJpeWkgZ8O2csO8bnTDvGxlbWUKCjxzY3JpcHQgYXN5bmMgc3JjPSJodHRwczovL3BsYXRmb3JtLnR3aXR0ZXIuY29tL3dpZGdldHMuanMiIGNoYXJzZXQ9InV0Zi04Ij48L3NjcmlwdD48YmxvY2txdW90ZSBjbGFzcz0idHdpdHRlci10d2VldCIgZGF0YS1sYW5nPSJlbiI+PHAgbGFuZz0iZW4iIGRpcj0ibHRyIj5TcHJlYWRzaGVldCB1c2VycyB1c2luZyA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvcnN0YXRzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jcnN0YXRzPC9hPjogIHdoZXJlJiMzOTtzIHRoZSBkYXRhPzxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHM/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNyc3RhdHM8L2E+IHVzZXJzIHVzaW5nIHNwcmVhZHNoZWV0czogIHdoZXJlJiMzOTtzIHRoZSBjb2RlPzwvcD4mbWRhc2g7IExlb25hcmQgS2llZmVyIChAbGVua2llZmVyKSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2xlbmtpZWZlci9zdGF0dXMvMTAxNTU4NzQ3NTU4MDk1NjY3Mj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5KdWx5IDcsIDIwMTg8L2E+PC9ibG9ja3F1b3RlPgoKLS0tCgojIFZlcml5aSBnw7Zyw7xudMO8bGVtZQoKYGBge3IsIHJlc3VsdHM9Im1hcmt1cCJ9CiMgbGlicmFyeShueWNmbGlnaHRzMTMpCiMgc3VtbWFyeShmbGlnaHRzKQpgYGAKCgoKYGBgClZpZXcoZGF0YSkKYGBgCgoKYGBgCmRhdGEKYGBgCgoKYGBgCmhlYWQKYGBgCgoKYGBgCnRhaWwKYGBgCgoKYGBgCmdsaW1wc2UKYGBgCgoKYGBgCnN0cgpgYGAKCgpgYGAKc2tpbXI6OnNraW0oKQpgYGAKCi0tLQoKCiMgVmVyaXlpIGRlxJ9pxZ90aXJtZQoKIyMgVmVyaXlpIGtvZCBpbGUgZGXEn2nFn3RpcmVsaW0KCiMjIFZlcml5aSBla2xlbnRpbGVybGUgZGXEn2nFn3Rpcm1lCgohWzpzY2FsZSA1MCVdKGZpZ3VyZXMvY2hhbmdlX2RhdGEucG5nKQoKCi0tLQoKCiMjIFJTdHVkaW8gYXJhY8SxbMSxxJ/EsXlsYSByZWNvZGUKCipxdWVzdGlvbnIqIHBha2V0aSBrdWxsYW7EsWxhY2FrCgohWzpzY2FsZSA1MCVdKGZpZ3VyZXMvbGV2ZWxfcmVjb2RlLnBuZykKCgotLS0KCgoKaHR0cHM6Ly9qdWJhLmdpdGh1Yi5pby9xdWVzdGlvbnIvYXJ0aWNsZXMvcmVjb2RpbmdfYWRkaW5zLmh0bWwKCgohW10oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2p1YmEvcXVlc3Rpb25yL21hc3Rlci9yZXNvdXJjZXMvc2NyZWVuc2hvdHMvaXJlY18xLnBuZykKCgotLS0KCiFbXShodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vanViYS9xdWVzdGlvbnIvbWFzdGVyL3Jlc291cmNlcy9zY3JlZW5zaG90cy9pcmVjXzIucG5nKQoKCi0tLQoKIVtdKGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9qdWJhL3F1ZXN0aW9uci9tYXN0ZXIvcmVzb3VyY2VzL3NjcmVlbnNob3RzL2lyZWNfMy5wbmcpCgoKLS0tCgojIEJhc2l0IHRhbsSxbWxhecSxY8SxIGlzdGF0aXN0aWtsZXIKCmBgYApzdW1tYXJ5KCkKYGBgCgpgYGAKbWVhbgpgYGAKCmBgYAptZWRpYW4KYGBgCgpgYGAKbWluCmBgYAoKYGBgCm1heApgYGAKCmBgYApzZApgYGAKCmBgYAp0YWJsZSgpCmBgYAoKLS0tCgoKYGBge3IgZGVzY3JpcHRpdmUsIGVjaG89VFJVRSwgaW5jbHVkZSA9IFRSVUV9CmxpYnJhcnkocmVhZHIpCmlyaXNkYXRhIDwtIHJlYWRfY3N2KCJkYXRhL2lyaXMuY3N2IikKCmptdjo6ZGVzY3JpcHRpdmVzKAogICAgZGF0YSA9IGlyaXNkYXRhLAogICAgdmFycyA9ICJTZXBhbC5MZW5ndGgiLAogICAgc3BsaXRCeSA9ICJTcGVjaWVzIiwKICAgIGZyZXEgPSBUUlVFLAogICAgaGlzdCA9IFRSVUUsCiAgICBkZW5zID0gVFJVRSwKICAgIGJhciA9IFRSVUUsCiAgICBib3ggPSBUUlVFLAogICAgdmlvbGluID0gVFJVRSwKICAgIGRvdCA9IFRSVUUsCiAgICBtb2RlID0gVFJVRSwKICAgIHN1bSA9IFRSVUUsCiAgICBzZCA9IFRSVUUsCiAgICB2YXJpYW5jZSA9IFRSVUUsCiAgICByYW5nZSA9IFRSVUUsCiAgICBzZSA9IFRSVUUsCiAgICBza2V3ID0gVFJVRSwKICAgIGt1cnQgPSBUUlVFLAogICAgcXVhcnQgPSBUUlVFLAogICAgcGNFcUdyID0gVFJVRSkKYGBgCgotLS0KCmBgYHtyIHNjYXR0ZXIsIGVjaG89VFJVRSwgaW5jbHVkZT1UUlVFfQojIGluc3RhbGwucGFja2FnZXMoInNjYXRyIikKCnNjYXRyOjpzY2F0KAogICAgZGF0YSA9IGlyaXNkYXRhLAogICAgeCA9ICJTZXBhbC5MZW5ndGgiLAogICAgeSA9ICJTZXBhbC5XaWR0aCIsCiAgICBncm91cCA9ICJTcGVjaWVzIiwKICAgIG1hcmcgPSAiZGVucyIsCiAgICBsaW5lID0gImxpbmVhciIsCiAgICBzZSA9IFRSVUUpCgpgYGAKCi0tLQoKIyMgc3VtbWFyeXRvb2xzCgpodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvc3VtbWFyeXRvb2xzL3ZpZ25ldHRlcy9JbnRyb2R1Y3Rpb24uaHRtbAoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KbGlicmFyeShzdW1tYXJ5dG9vbHMpCnN1bW1hcnl0b29sczo6ZnJlcShpcmlzJFNwZWNpZXMsIHN0eWxlID0gInJtYXJrZG93biIpCmBgYAoKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kc3VtbWFyeXRvb2xzOjpmcmVxKGlyaXMkU3BlY2llcywgcmVwb3J0Lm5hcyA9IEZBTFNFLCBzdHlsZSA9ICJybWFya2Rvd24iLCBoZWFkaW5ncyA9IEZBTFNFKQpgYGAKCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQp3aXRoKHRvYmFjY28sIHByaW50KGN0YWJsZShzbW9rZXIsIGRpc2Vhc2VkKSwgbWV0aG9kID0gJ3JlbmRlcicpKQpgYGAKCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQp3aXRoKHRvYmFjY28sCiAgICAgcHJpbnQoY3RhYmxlKHNtb2tlciwgZGlzZWFzZWQsIHByb3AgPSAnbicsIHRvdGFscyA9IEZBTFNFKSwKICAgICAgICAgICBvbWl0LmhlYWRpbmdzID0gVFJVRSwgbWV0aG9kID0gInJlbmRlciIpKQpgYGAKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30Kc3VtbWFyeXRvb2xzOjpkZXNjcihpcmlzLCBzdHlsZSA9ICJybWFya2Rvd24iKQpgYGAKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KZGVzY3IoaXJpcywKICAgICAgc3RhdHMgPSBjKCJtZWFuIiwgInNkIiwgIm1pbiIsICJtZWQiLCAibWF4IiksCiAgICAgIHRyYW5zcG9zZSA9IFRSVUUsCiAgICAgIGhlYWRpbmdzID0gRkFMU0UsCiAgICAgIHN0eWxlID0gInJtYXJrZG93biIpCmBgYAoKLS0tCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQojIHZpZXcoZGZTdW1tYXJ5KGlyaXMpKQoKYGBgCgoKIVtdKGZpZ3VyZXMvZGZzdW1tYXJ5LnBuZykKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KZGZTdW1tYXJ5KHRvYmFjY28sCiAgICAgICAgICBwbGFpbi5hc2NpaSA9IEZBTFNFLAogICAgICAgICAgc3R5bGUgPSAiZ3JpZCIpCmBgYAoKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KCiMgRmlyc3Qgc2F2ZSB0aGUgcmVzdWx0cwoKaXJpc19zdGF0c19ieV9zcGVjaWVzIDwtIGJ5KGRhdGEgPSBpcmlzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5ESUNFUyA9IGlyaXMkU3BlY2llcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZVTiA9IGRlc2NyLCBzdGF0cyA9IGMoIm1lYW4iLCAic2QiLCAibWluIiwgIm1lZCIsICJtYXgiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zcG9zZSA9IFRSVUUpCgojIFRoZW4gdXNlIHZpZXcoKSwgbGlrZSBzbzoKCnZpZXcoaXJpc19zdGF0c19ieV9zcGVjaWVzLCBtZXRob2QgPSAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgoKLS0tCgoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KIyB2aWV3KGlyaXNfc3RhdHNfYnlfc3BlY2llcykKYGBgCgohW10oZmlndXJlcy9EZXNjcmlwdGl2ZVN0YXRpc3RpY3MucG5nKQoKLS0tCgpgYGB7ciwgaW5jbHVkZT1UUlVFLCBjb21tZW50PU5BLCBwcm9tcHQ9RkFMU0UsIGNhY2hlPUZBTFNFLCBlY2hvPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQpkYXRhKHRvYmFjY28pICMgdG9iYWNjbyBpcyBhbiBleGFtcGxlIGRhdGFmcmFtZSBpbmNsdWRlZCBpbiB0aGUgcGFja2FnZQpCTUlfYnlfYWdlIDwtIHdpdGgodG9iYWNjbywKICAgICAgICAgICAgICAgICAgIGJ5KEJNSSwgYWdlLmdyLCBkZXNjciwKICAgICAgICAgICAgICAgICAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpKSkKdmlldyhCTUlfYnlfYWdlLCAicGFuZGVyIiwgc3R5bGUgPSAicm1hcmtkb3duIikKYGBgCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CkJNSV9ieV9hZ2UgPC0gd2l0aCh0b2JhY2NvLAogICAgICAgICAgICAgICAgICAgYnkoQk1JLCBhZ2UuZ3IsIGRlc2NyLCAgdHJhbnNwb3NlID0gVFJVRSwKICAgICAgICAgICAgICAgICAgICAgIHN0YXRzID0gYygibWVhbiIsICJzZCIsICJtaW4iLCAibWVkIiwgIm1heCIpKSkKCnZpZXcoQk1JX2J5X2FnZSwgInBhbmRlciIsIHN0eWxlID0gInJtYXJrZG93biIsIG9taXQuaGVhZGluZ3MgPSBUUlVFKQpgYGAKCi0tLQoKYGBge3IsIGluY2x1ZGU9VFJVRSwgY29tbWVudD1OQSwgcHJvbXB0PUZBTFNFLCBjYWNoZT1GQUxTRSwgZWNobz1UUlVFLCByZXN1bHRzPSdhc2lzJ30KdG9iYWNjb19zdWJzZXQgPC0gdG9iYWNjb1sgLGMoImdlbmRlciIsICJhZ2UuZ3IiLCAic21va2VyIildCmZyZXFfdGFibGVzIDwtIGxhcHBseSh0b2JhY2NvX3N1YnNldCwgZnJlcSkKCiMgdmlldyhmcmVxX3RhYmxlcywgZm9vdG5vdGUgPSBOQSwgZmlsZSA9ICdmcmVxLXRhYmxlcy5odG1sJykKYGBgCgotLS0KCmBgYHtyLCBpbmNsdWRlPVRSVUUsIGNvbW1lbnQ9TkEsIHByb21wdD1GQUxTRSwgY2FjaGU9RkFMU0UsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9CndoYXQuaXMoaXJpcykKYGBgCgotLS0KCmBgYHtyfQpmcmVxKHRvYmFjY28kZ2VuZGVyLCBzdHlsZSA9ICdybWFya2Rvd24nKQpgYGAKCi0tLQoKYGBge3J9CnByaW50KGZyZXEodG9iYWNjbyRnZW5kZXIpLCBtZXRob2QgPSAncmVuZGVyJykKYGBgCgotLS0KCiMjIHNraW1yCgpgYGAKbGlicmFyeShza2ltcikKc2tpbShkZikKYGBgCgotLS0KCiMjIERhdGFFeHBsb3JlcgoKYGBgCmxpYnJhcnkoRGF0YUV4cGxvcmVyKQpEYXRhRXhwbG9yZXI6OmNyZWF0ZV9yZXBvcnQoZGYpCmBgYAoKClshW10oaHR0cHM6Ly9zdGF0aWMxLnNxdWFyZXNwYWNlLmNvbS9zdGF0aWMvNThlZWY4ODQ2YTQ5NjNlNDI5Njg3YTRkL3QvNWJkZmMyZmI0ZDdhOWMwNGVlNTBiN2FhLzE1NDEzOTExNjA3MDIvZGF0YUV4cGxvcmVyR2lmTGcuZ2lmP2Zvcm1hdD0xNTAwdyldKGh0dHBzOi8vd3d3LmxpdHRsZW1pc3NkYXRhLmNvbS9ibG9nL3NpbXBsZS1lZGEpCgoKCi0tLQoKIyMgaW5zcGVjdGRmCgpodHRwczovL2dpdGh1Yi5jb20vYWxhc3RhaXJydXNod29ydGgvaW5zcGVjdGRmCgoKLS0tCgojIyBHcmFmaWtsZXIKCmBgYHtyfQojIGxpYnJhcnkoZ2dwbG90MikKIyBsaWJyYXJ5KG1vc2FpYykKIyBtUGxvdChpcmlzZGF0YSkKYGBgCgotLS0KCgpgYGB7ciwgcmVzdWx0cz0iYXNpcyJ9CmN0YWJsZSh0b2JhY2NvJGdlbmRlciwgdG9iYWNjbyRzbW9rZXIsIHN0eWxlID0gJ3JtYXJrZG93bicpCmBgYAoKLS0tCgoKYGBge3J9CnByaW50KGN0YWJsZSh0b2JhY2NvJGdlbmRlciwgdG9iYWNjbyRzbW9rZXIpLCBtZXRob2QgPSAncmVuZGVyJykKYGBgCgoKLS0tCgpgYGAKZGVzY3IodG9iYWNjbywgc3R5bGUgPSAncm1hcmtkb3duJykKCnByaW50KGRlc2NyKHRvYmFjY28pLCBtZXRob2QgPSAncmVuZGVyJywgdGFibGUuY2xhc3NlcyA9ICdzdC1zbWFsbCcpCgpkZlN1bW1hcnkodG9iYWNjbywgc3R5bGUgPSAnZ3JpZCcsIHBsYWluLmFzY2lpID0gRkFMU0UpCgpwcmludChkZlN1bW1hcnkodG9iYWNjbywgZ3JhcGgubWFnbmlmID0gMC43NSksIG1ldGhvZCA9ICdyZW5kZXInKQpgYGAKCgotLS0KCgoKPGJsb2NrcXVvdGUgY2xhc3M9InR3aXR0ZXItdHdlZXQiIGRhdGEtbGFuZz0iZW4iPjxwIGxhbmc9ImVuIiBkaXI9Imx0ciI+SGVyZSwgYnVpbGRpbmcgdXAgYSA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvZ2dwbG90Mj9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I2dncGxvdDI8L2E+IGFzIHNsb3dseSBhcyBwb3NzaWJsZSwgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL3JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I3JzdGF0czwvYT4uICBJbmNyZW1lbnRhbCBhZGp1c3RtZW50cy4gIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vaGFzaHRhZy9yc3RhdHN0ZWFjaGluZ2lkZWFzP3NyYz1oYXNoJmFtcDtyZWZfc3JjPXR3c3JjJTVFdGZ3Ij4jcnN0YXRzdGVhY2hpbmdpZGVhczwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90LmNvL25VdWxRbDhiUGgiPnBpYy50d2l0dGVyLmNvbS9uVXVsUWw4YlBoPC9hPjwvcD4mbWRhc2g7IEdpbmEgUmV5bm9sZHMgKEBFdmFNYWVSZXkpIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vRXZhTWFlUmV5L3N0YXR1cy8xMDI5MTA0NjU2NzYzNTcyMjI2P3JlZl9zcmM9dHdzcmMlNUV0ZnciPkF1Z3VzdCAxMywgMjAxODwvYT48L2Jsb2NrcXVvdGU+PHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PgoKCi0tLQoKClshW10oaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL2RyZWFtUnMvZXNxdWlzc2UvbWFzdGVyL21hbi9maWd1cmVzL2VzcXVpc3NlLmdpZildKGh0dHBzOi8vZ2l0aHViLmNvbS9kcmVhbVJzL2VzcXVpc3NlKQoKCjxibG9ja3F1b3RlIGNsYXNzPSJ0d2l0dGVyLXR3ZWV0IiBkYXRhLWxhbmc9ImVuIj48cCBsYW5nPSJlbiIgZGlyPSJsdHIiPkRyZWFtaW5nIG9mIGEgZmFuY3kgPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL1JzdGF0cz9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I1JzdGF0czwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL2dncGxvdD9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I2dncGxvdDwvYT4gPGEgaHJlZj0iaHR0cHM6Ly90d2l0dGVyLmNvbS9oYXNodGFnL2RhdGF2aXo/c3JjPWhhc2gmYW1wO3JlZl9zcmM9dHdzcmMlNUV0ZnciPiNkYXRhdml6PC9hPiBidXQgc3RpbGwgc2NhcmVkIG9mIHR5cGluZyA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL2hhc2h0YWcvY29kZT9zcmM9aGFzaCZhbXA7cmVmX3NyYz10d3NyYyU1RXRmdyI+I2NvZGU8L2E+PyA8YSBocmVmPSJodHRwczovL3R3aXR0ZXIuY29tL19wdmljdG9ycj9yZWZfc3JjPXR3c3JjJTVFdGZ3Ij5AX3B2aWN0b3JyPC9hPiBlc3F1aXNzZSBwYWNrYWdlIGhhcyB5b3UgY292ZXJlZCA8YSBocmVmPSJodHRwczovL3QuY28vMXZJRFhjVkFBRiI+aHR0cHM6Ly90LmNvLzF2SURYY1ZBQUY8L2E+IDxhIGhyZWY9Imh0dHBzOi8vdC5jby9SbFRrcHRuck52Ij5waWMudHdpdHRlci5jb20vUmxUa3B0bnJOdjwvYT48L3A+Jm1kYXNoOyBSYWRvc2xhdyBQYW5jemFrIChAUlBhbmN6YWspIDxhIGhyZWY9Imh0dHBzOi8vdHdpdHRlci5jb20vUlBhbmN6YWsvc3RhdHVzLzEwNDcwMTk1ODg2NTgwNDA4MzI/cmVmX3NyYz10d3NyYyU1RXRmdyI+T2N0b2JlciAyLCAyMDE4PC9hPjwvYmxvY2txdW90ZT4KPHNjcmlwdCBhc3luYyBzcmM9Imh0dHBzOi8vcGxhdGZvcm0udHdpdHRlci5jb20vd2lkZ2V0cy5qcyIgY2hhcnNldD0idXRmLTgiPjwvc2NyaXB0PgoKCgo8IS0tICMjIFRhYmxvbGFyIC0tPgoKCi0tLQoKIyBCYXrEsSBhcmF5w7x6bGVyCgoKIyMgUmNtZHIKCmBgYApsaWJyYXJ5KFJjbWRyKQoKUmNtZHI6OkNvbW1hbmRlcigpCgpgYGAKCgotIEEgQ29tcGFyYXRpdmUgUmV2aWV3IG9mIHRoZSBSIENvbW1hbmRlciBHVUkgZm9yIFIKCmh0dHA6Ly9yNHN0YXRzLmNvbS9hcnRpY2xlcy9zb2Z0d2FyZS1yZXZpZXdzL3ItY29tbWFuZGVyLwoKCi0tLQoKIyMgamFtb3ZpCgpodHRwczovL3d3dy5qYW1vdmkub3JnLwoKIVshW10oaHR0cHM6Ly93d3cuamFtb3ZpLm9yZy9hc3NldHMvbWFpbi1zY3JlZW5zaG90LnBuZyldKGh0dHBzOi8vd3d3LmphbW92aS5vcmcvKQoKCmh0dHBzOi8vYmxvZy5qYW1vdmkub3JnLzIwMTgvMDcvMzAvcmouaHRtbAoKIVshW10oaHR0cHM6Ly9ibG9nLmphbW92aS5vcmcvYXNzZXRzL2ltYWdlcy9yai5wbmcpXShodHRwczovL2Jsb2cuamFtb3ZpLm9yZy8yMDE4LzA3LzMwL3JqLmh0bWwpCgotLS0KCiMgUiBuZXJlZGVuIMO2xJ9yZW5pbGlyCgpodHRwczovL3NiYWxjaS5naXRodWIuaW8vTXlSQ29kZXNGb3JEYXRhQW5hbHlzaXMvV2hlcmVUb0xlYXJuUi5uYi5odG1sCgotLS0KCiMgU29ucmFraSBLb251bGFyCgotIFJTdHVkaW8gaWxlIEdpdEh1YiBrdWxsYW7EsW3EsQotIFIgTWFya2Rvd24gdmUgUiBOb3RlYm9vayBpbGUgdGVrcmFybGFuYWJpbGlyIHJhcG9yCi0gSGlwb3RleiB0ZXN0bGVyaQoKCgotLS0tLQoKIyBHZXJpIEJpbGRpcmltCgotIEdlcmkgYmlsZGlyaW0gacOnaW4gdMSxa2xhecSxbsSxejogX1tHZXJpIGJpbGRpcmltIGZvcm11XShodHRwczovL2dvby5nbC9mb3Jtcy9ZakdaNURIZ3RQbFIxUm5CMylfCgoKLS0tCgo8c2NyaXB0IGlkPSJkc3EtY291bnQtc2NyIiBzcmM9Ii8vaHR0cHMtc2JhbGNpLWdpdGh1Yi1pby5kaXNxdXMuY29tL2NvdW50LmpzIiBhc3luYz48L3NjcmlwdD4KCjxkaXYgaWQ9ImRpc3F1c190aHJlYWQiPjwvZGl2Pgo8c2NyaXB0PgoKLyoqCiogIFJFQ09NTUVOREVEIENPTkZJR1VSQVRJT04gVkFSSUFCTEVTOiBFRElUIEFORCBVTkNPTU1FTlQgVEhFIFNFQ1RJT04gQkVMT1cgVE8gSU5TRVJUIERZTkFNSUMgVkFMVUVTIEZST00gWU9VUiBQTEFURk9STSBPUiBDTVMuCiogIExFQVJOIFdIWSBERUZJTklORyBUSEVTRSBWQVJJQUJMRVMgSVMgSU1QT1JUQU5UOiBodHRwczovL2Rpc3F1cy5jb20vYWRtaW4vdW5pdmVyc2FsY29kZS8jY29uZmlndXJhdGlvbi12YXJpYWJsZXMqLwovKgp2YXIgZGlzcXVzX2NvbmZpZyA9IGZ1bmN0aW9uICgpIHsKdGhpcy5wYWdlLnVybCA9IFBBR0VfVVJMOyAgLy8gUmVwbGFjZSBQQUdFX1VSTCB3aXRoIHlvdXIgcGFnZSdzIGNhbm9uaWNhbCBVUkwgdmFyaWFibGUKdGhpcy5wYWdlLmlkZW50aWZpZXIgPSBQQUdFX0lERU5USUZJRVI7IC8vIFJlcGxhY2UgUEFHRV9JREVOVElGSUVSIHdpdGggeW91ciBwYWdlJ3MgdW5pcXVlIGlkZW50aWZpZXIgdmFyaWFibGUKfTsKKi8KKGZ1bmN0aW9uKCkgeyAvLyBET04nVCBFRElUIEJFTE9XIFRISVMgTElORQp2YXIgZCA9IGRvY3VtZW50LCBzID0gZC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTsKcy5zcmMgPSAnaHR0cHM6Ly9odHRwcy1zYmFsY2ktZ2l0aHViLWlvLmRpc3F1cy5jb20vZW1iZWQuanMnOwpzLnNldEF0dHJpYnV0ZSgnZGF0YS10aW1lc3RhbXAnLCArbmV3IERhdGUoKSk7CihkLmhlYWQgfHwgZC5ib2R5KS5hcHBlbmRDaGlsZChzKTsKfSkoKTsKPC9zY3JpcHQ+Cjxub3NjcmlwdD5QbGVhc2UgZW5hYmxlIEphdmFTY3JpcHQgdG8gdmlldyB0aGUgPGEgaHJlZj0iaHR0cHM6Ly9kaXNxdXMuY29tLz9yZWZfbm9zY3JpcHQiPmNvbW1lbnRzIHBvd2VyZWQgYnkgRGlzcXVzLjwvYT48L25vc2NyaXB0PgoKCi0tLQoKCmBgYAojIFNhdmUgRmluYWwgRGF0YQoKc2F2ZWQgZGF0YSBhZnRlciBhbmFseXNpcyB0byBgRGF0YS1BZnRlci1BbmFseXNpcy54bHN4YC4KCnNhdmVSRFMobXlkYXRhLCAiRGF0YS1BZnRlci1BbmFseXNpcy5yZHMiKQoKd3JpdGV4bDo6d3JpdGVfeGxzeChteWRhdGEsICJEYXRhLUFmdGVyLUFuYWx5c2lzLnhsc3giKQoKZmlsZS5pbmZvKCJEYXRhLUFmdGVyLUFuYWx5c2lzLnhsc3giKSRjdGltZQoKYGBgCgotLS0KCgojIExpYnJhcmllcyBVc2VkCgpgYGB7cn0KY2l0YXRpb24oKQpgYGAKCmBgYApjaXRhdGlvbigidGlkeXZlcnNlIikKY2l0YXRpb24oImZvcmVpZ24iKQpjaXRhdGlvbigidGlkeWxvZyIpCmNpdGF0aW9uKCJqYW5pdG9yIikKY2l0YXRpb24oImptdiIpCmNpdGF0aW9uKCJ0YW5ncmFtIikKY2l0YXRpb24oImZpbmFsZml0IikKY2l0YXRpb24oInN1bW1hcnl0b29scyIpCmNpdGF0aW9uKCJnZ3N0YXRwbG90IikKY2l0YXRpb24oInJlYWR4bCIpCmBgYAoKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmNpdGF0aW9uKCJ0aWR5dmVyc2UiKQpjaXRhdGlvbigiZm9yZWlnbiIpCmNpdGF0aW9uKCJ0aWR5bG9nIikKY2l0YXRpb24oImphbml0b3IiKQpjaXRhdGlvbigiam12IikKY2l0YXRpb24oInRhbmdyYW0iKQpjaXRhdGlvbigiZmluYWxmaXQiKQpjaXRhdGlvbigic3VtbWFyeXRvb2xzIikKY2l0YXRpb24oImdnc3RhdHBsb3QiKQpjaXRhdGlvbigicmVhZHhsIikKYGBgCgoKLS0tCgoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQpyZXBvcnQ6OmNpdGVfcGFja2FnZXMoc2Vzc2lvbiA9IHNlc3Npb25JbmZvKCkpCmBgYAoKCi0tLQoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgotLS0KCgojIE5vdGVzICAKCkNvbXBsZXRlZCBvbiBgciBTeXMudGltZSgpYC4gIAoKU2VyZGFyIEJhbGNpLCBNRCwgUGF0aG9sb2dpc3QgIApkcnNlcmRhcmJhbGNpQGdtYWlsLmNvbSAgCmh0dHBzOi8vcnB1YnMuY29tL3NiYWxjaS9DViAgIApodHRwczovL3NiYWxjaS5naXRodWIuaW8vICAKaHR0cHM6Ly9naXRodWIuY29tL3NiYWxjaSAgCgoKLS0tCgpgYGB7cn0KQ29tbWl0TWVzc2FnZSA8LSBwYXN0ZSgidXBkYXRlZCBvbiAiLCBTeXMudGltZSgpLCBzZXAgPSAiIikKCndkIDwtIGdldHdkKCkKCmdpdENvbW1hbmQgPC0gcGFzdGUoImNkICIsIHdkLCAiIFxuIGdpdCBhZGQgLiBcbiBnaXQgY29tbWl0IC0tbWVzc2FnZSAnIiwgQ29tbWl0TWVzc2FnZSwgIicgXG4gZ2l0IHB1c2ggb3JpZ2luIG1hc3RlciBcbiIsIHNlcCA9ICIiKQoKc3lzdGVtKGNvbW1hbmQgPSBnaXRDb21tYW5kLCBpbnRlcm4gPSBUUlVFCikKCmBgYAoKCgoKCgoKCg==